package org.zn.note.common.util;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @ClassName ThreadUtil
 * @Author zn
 * @Date 2019/3/28 14:31
 **/
public class ThreadUtil {

    public static void println(String s) {
        printThread(s);
    }

    public static void printThread(String s) {
        System.out.println("[" + Thread.currentThread().getName() + "] " + s);
    }

    public static void printThreadTask(String task, String s) {
        printThread("[TASK " + task + "] " + s);
    }

    public static void sleep(long time) {
        sleep(TimeUnit.SECONDS, time);
    }

    public static void sleep(TimeUnit timeUnit, long time) {
        try {
            timeUnit.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void performanceTest(Runnable task, int threadNum, int execNum) {
        performanceTest(task, threadNum, execNum, false);
    }

    public static void performanceTest(Runnable task, int threadNum, int execNum, boolean printEachTime) {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(threadNum, threadNum,
                0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
        threadPool.prestartAllCoreThreads();
        CountDownLatch latch = new CountDownLatch(execNum);
        AtomicLong execTime = new AtomicLong(0L);
        for(int i=0; i<execNum; i++)
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    long startTime = System.currentTimeMillis();
                    task.run();
                    long spendTime = System.currentTimeMillis() - startTime;
                    if(printEachTime)
                        System.out.println("单次执行时间：" + spendTime);
                    execTime.addAndGet(spendTime);
                    latch.countDown();
                }
            });
        threadPool.shutdown();
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("并发线程个数：" + threadNum);
        System.out.println("任务执行次数：" + execNum);
        System.out.println("平均执行时间：" + (execTime.longValue()/execNum));
        System.out.println("总的执行时间：" + execTime.longValue());
    }

    public static void main(String[] args) {
        performanceTest(new Runnable() {
            @Override
            public void run() {
                try {
                    TimeUnit.SECONDS.sleep(1L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, 10, 100);
    }
}
